package io.kimmking.rpcfx.proxy;


import com.alibaba.fastjson.parser.ParserConfig;
import io.kimmking.rpcfx.api.Filter;
import io.kimmking.rpcfx.api.LoadBalancer;
import io.kimmking.rpcfx.api.Router;
import io.kimmking.rpcfx.register.center.api.DiscoveryInfo;
import io.kimmking.rpcfx.register.center.api.ProviderInfo;
import io.kimmking.rpcfx.register.center.zookeeper.ZookeeperDiscovery;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public final class RpcfxCglib {

    ZookeeperDiscovery zookeeperDiscovery;
    private final LoadBalancer loadBalancer;
    private final Router router;
    public RpcfxCglib(String zkServer , String namespace, LoadBalancer loadBalancer, Router router){
        this.zookeeperDiscovery = new ZookeeperDiscovery(zkServer,namespace);
        this.loadBalancer = loadBalancer;
        this.router = router;
    }

    static {
        ParserConfig.getGlobalInstance().addAccept("io.kimmking");
    }

    public  <T> T createMock(final Class<T> serviceClass,Class<? extends  T> mockClass) {
        try {
            return mockClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
    public  <T> T create(final Class<T> serviceClass,DiscoveryInfo discoveryInfo, Filter... filters) {
        Enhancer enhancer = new Enhancer();
        //设置目标类的字节码文件
        enhancer.setSuperclass(serviceClass);
        //设置回调函数
        CustomInterceptor interceptor = new CustomInterceptor(serviceClass,loadBalancer, filters);
        zookeeperDiscovery.discovery(discoveryInfo,interceptor,router);
        enhancer.setCallback(interceptor);
        //这里的creat方法就是正式创建代理类
        return  (T) enhancer.create();
    }


    public  Object  genericCall(DiscoveryInfo discoveryInfo,String method,Object[]args, Filter... filters) {
        List<ProviderInfo> infos = zookeeperDiscovery.discovery(discoveryInfo, router);
        return CustomInterceptor.call(discoveryInfo.getServiceName(),method,args,filters,loadBalancer,infos);
    }



}
